/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include <节点/节点.h>
#include "节点/输入输出节点.h"


//#define f_多边形_添加顶点节点cxx fn_多边形_添加顶点节点
//uvec2 f_多边形_添加顶点节点cxx(S_多边形* self, void* verts);

struct S_物体;


uvec2* f_多边形_边_data(S_边* self);


class C_网格节点 : public C_节点基类 {
	S_物体* m_Ob;

public:
	C_网格节点(S_设备环境& ctx);
	~C_网格节点();

	S_Props		m_位置;
	S_Props		m_旋转;
	S_Props		m_缩放;

	bool	f_update();
	S_物体* f_get虚拟体();
	void	f_入回收();
	void	f_回收();

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建网格节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_载入网格节点(S_设备环境& ctx, FILE* f);
void		f_node_保存网格节点(C_节点基类* n, FILE* f);



class C_平面网格节点 : public C_节点基类 {
	S_物体* m_Ob;

public:
	C_平面网格节点(S_设备环境& ctx);
	~C_平面网格节点();

	S_Props		m_位置;
	S_Props		m_旋转;
	S_Props		m_缩放;

	bool	f_update();
	S_物体* f_get虚拟体();
	void	f_入回收();
	void	f_回收();

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建平面网格节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_载入平面网格节点(S_设备环境& ctx, FILE* f);
void		f_node_保存平面网格节点(C_节点基类* n, FILE* f);







class C_球体网格节点 : public C_节点基类 {
	S_物体* m_Ob;
public:
	C_球体网格节点(S_设备环境& ctx);
	~C_球体网格节点();

	S_Props		m_位置;
	S_Props		m_旋转;
	S_Props		m_缩放;

	bool	f_update();
	S_物体* f_get虚拟体();
	void	f_入回收();
	void	f_回收();

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建球体网格节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_载入球体网格节点(S_设备环境& ctx, FILE* f);
void		f_node_保存球体网格节点(C_节点基类* n, FILE* f);







class C_矩形网格节点 : public C_节点基类 {
	S_物体* m_Ob;
public:
	C_矩形网格节点(S_设备环境& ctx);
	~C_矩形网格节点();

	S_Props		m_位置;
	S_Props		m_旋转;
	S_Props		m_缩放;

	bool	f_update();
	S_物体* f_get虚拟体();
	void	f_入回收();
	void	f_回收();

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建矩形网格节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_载入矩形网格节点(S_设备环境& ctx, FILE* f);
void		f_node_保存矩形网格节点(C_节点基类* n, FILE* f);








class C_线框立方体节点 : public C_节点基类 {
	S_物体* m_Ob;
public:
	C_线框立方体节点(S_设备环境& ctx);
	~C_线框立方体节点();

	S_Props		m_位置;
	S_Props		m_旋转;
	S_Props		m_缩放;

	bool	f_update();
	S_物体* f_get虚拟体();
	void	f_入回收();
	void	f_回收();

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建线框立方体节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_载入线框立方体节点(S_设备环境& ctx, FILE* f);
void		f_node_保存线框立方体节点(C_节点基类* n, FILE* f);



class C_几何节点 : public C_节点基类 {
	S_物体* m_Ob;
	std::vector<S_多边形*>   m_多边形;

	std::vector<C_节点基类*> m_InNodes;
	std::vector<C_节点基类*> m_OutNudes;

public:
	C_几何节点(S_设备环境& ctx, C_节点树* link_tree = nullptr);
	~C_几何节点();

	//S_Props                 m_函数名称;
	expand_接口函数_几何节点 m_函数指针;

	S_Props		m_数量;
	
	S_Props		m_合并顶点;
	S_Props		m_合并顶点阈;
	S_Props		m_计算平滑法线;
	S_Props		m_生成GPU网格;

	bool	f_update();

	
	void f_get子集输入节点(std::vector<C_节点基类*>& inNodes);
	void f_get子集输出节点(std::vector<C_节点基类*>& outNodes);
	

	std::string	f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放);
	void		f_异步解算();

	S_物体* f_get虚拟体();
	void	f_入回收();
	void	f_回收();

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);

protected:
	bool		m_是否链接;
};

C_节点基类* f_node_创建几何节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_载入几何节点(S_设备环境& ctx, FILE* f);
void		f_node_保存几何节点(C_节点基类* n, FILE* f);




class C_几何ID节点 : public C_节点基类 {
	//C_节点树* m_子树;
public:
	C_几何ID节点(S_设备环境& ctx);
	~C_几何ID节点();

	bool		f_update();
	std::string	DEF_节点编译函数;
};

C_节点基类* f_node_创建几何ID节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载几何ID节点(S_设备环境& ctx, FILE* f);
void		f_node_保存几何ID节点(C_节点基类* n, FILE* f);




class C_当前多边形节点 : public C_节点基类 {
	//C_节点树* m_子树;
public:
	C_当前多边形节点(S_设备环境& ctx);
	~C_当前多边形节点();

	bool		f_update();
	std::string	DEF_节点编译函数;
	//void	f_读取(FILE* f);
	//void	f_写入(FILE* f);
};

C_节点基类* f_node_创建当前多边形节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载当前多边形节点(S_设备环境& ctx, FILE* f);
void		f_node_保存当前多边形节点(C_节点基类* n, FILE* f);





class C_构建多边形节点 : public C_节点基类 {
	S_物体* m_Ob;
public:
	C_构建多边形节点(S_设备环境& ctx);
	~C_构建多边形节点();

	bool	f_update();
	//void	f_读取(FILE* f);
	//void	f_写入(FILE* f);
};

C_节点基类* f_node_创建构建多边形节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_载入构建多边形节点(S_设备环境& ctx, FILE* f);
void		f_node_保存构建多边形节点(C_节点基类* n, FILE* f);



class C_多边形顶点节点 : public C_节点基类 {
	S_物体* m_Ob;
public:
	C_多边形顶点节点(S_设备环境& ctx);
	~C_多边形顶点节点();

	bool	f_update();
	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
	S_物体* f_get虚拟体();
	void	f_入回收();
	void	f_回收();

};

C_节点基类* f_node_创建多边形顶点节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_载入多边形顶点节点(S_设备环境& ctx, FILE* f);
void		f_node_保存多边形顶点节点(C_节点基类* n, FILE* f);



class C_基本多边形节点 : public C_节点基类 {
	S_物体* m_Ob;
public:
	C_基本多边形节点(S_设备环境& ctx);
	~C_基本多边形节点();

	S_Props		m_几何网格类型;
	S_Props		m_加入到场景;

	bool	f_update();
	std::string DEF_节点编译函数;
	void    f_Copy(const C_节点基类* node);
	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建基本多边形节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_载入基本多边形节点(S_设备环境& ctx, FILE* f);
void		f_node_保存基本多边形节点(C_节点基类* n, FILE* f);



class C_多边形添加顶点节点 : public C_节点基类 {
	S_物体* m_Ob;
public:
	C_多边形添加顶点节点(S_设备环境& ctx);
	~C_多边形添加顶点节点();

	S_Props m_构建方式;
	bool	f_update();
	std::string	f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放);

	S_物体* f_get虚拟体();
	void	f_入回收();
	void	f_回收();
};

C_节点基类* f_node_创建多边形添加顶点节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_载入多边形添加顶点节点(S_设备环境& ctx, FILE* f);
void		f_node_保存多边形添加顶点节点(C_节点基类* n, FILE* f);



class C_构建多边形边节点 : public C_节点基类 {
	S_物体* m_Ob;
public:
	C_构建多边形边节点(S_设备环境& ctx);
	~C_构建多边形边节点();

	S_Props	m_边模式;
	bool	f_update();
	std::string	f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放);

	S_物体* f_get虚拟体();
	void	f_入回收();
	void	f_回收();
	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建构建多边形边节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_载入构建多边形边节点(S_设备环境& ctx, FILE* f);
void		f_node_保存构建多边形边节点(C_节点基类* n, FILE* f);



class C_多边形索引节点 : public C_节点基类 {
	
public:
	C_多边形索引节点(S_设备环境& ctx);
	~C_多边形索引节点();

	bool	f_update();
	std::string DEF_节点编译函数;
};

C_节点基类* f_node_创建多边形索引节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_载入多边形索引节点(S_设备环境& ctx, FILE* f);
void		f_node_保存多边形索引节点(C_节点基类* n, FILE* f);




class C_添加多边形元素节点 : public C_节点基类 {

public:
	C_添加多边形元素节点(S_设备环境& ctx);
	
	bool	f_update();
	std::string DEF_节点编译函数;
};

C_节点基类* f_node_创建添加多边形元素节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_载入添加多边形元素节点(S_设备环境& ctx, FILE* f);
void		f_node_保存添加多边形元素节点(C_节点基类* n, FILE* f);





class C_添加纹理坐标节点 : public C_节点基类 {

public:
	C_添加纹理坐标节点(S_设备环境& ctx);
	~C_添加纹理坐标节点();

	bool	f_update();
	std::string	DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建构建多边形纹理坐标节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_载入构建多边形纹理坐标节点(S_设备环境& ctx, FILE* f);
void		f_node_保存构建多边形纹理坐标节点(C_节点基类* n, FILE* f);




class C_投影纹理坐标节点 : public C_节点基类 {
	S_物体* m_Ob;
public:
	C_投影纹理坐标节点(S_设备环境& ctx);
	~C_投影纹理坐标节点();

	S_Props	m_投影类型;

	bool	f_update();
	std::string	DEF_节点编译函数;

	S_物体* f_get虚拟体();
	void	f_入回收();
	void	f_回收();

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建投影纹理坐标节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_载入投影纹理坐标节点(S_设备环境& ctx, FILE* f);
void		f_node_保存投影纹理坐标节点(C_节点基类* n, FILE* f);




class C_设置面材质槽ID节点 : public C_节点基类 {
	
public:
	C_设置面材质槽ID节点(S_设备环境& ctx);
	~C_设置面材质槽ID节点();

	bool	f_update();
	std::string	DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建设置面材质槽ID节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_载入设置面材质槽ID节点(S_设备环境& ctx, FILE* f);
void		f_node_保存设置面材质槽ID节点(C_节点基类* n, FILE* f);





class C_网格采样节点 : public C_节点基类 {

public:
	C_网格采样节点(S_设备环境& ctx);
	~C_网格采样节点();

	S_Props	m_随机;
	S_Props	m_平滑法线;
	bool	f_update();
	std::string	DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建网格采样节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_载入网格采样节点(S_设备环境& ctx, FILE* f);
void		f_node_保存网格采样节点(C_节点基类* n, FILE* f);



class C_点在网格内节点 : public C_节点基类 {
	
public:
	C_点在网格内节点(S_设备环境& ctx);
	~C_点在网格内节点();

	S_Props	m_反向;
	bool	f_update();
	std::string	DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建点在网格内节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_载入点在网格内节点(S_设备环境& ctx, FILE* f);
void		f_node_保存点在网格内节点(C_节点基类* n, FILE* f);



class C_拷贝网格数据节点 : public C_节点基类 {

public:
	C_拷贝网格数据节点(S_设备环境& ctx);
	~C_拷贝网格数据节点();

	//S_Props	m_顶点;
	//S_Props	m_索引;
	bool	f_update();
	//std::string	DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建拷贝网格数据节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_载入拷贝网格数据节点(S_设备环境& ctx, FILE* f);
void		f_node_保存拷贝网格数据节点(C_节点基类* n, FILE* f);
























